package cn.com.gome.generator.logic;

import cn.com.gome.framework.dao.entity.TblProjectBasicInfo;
import com.gomeplus.frame.exception.LogicsException;
import com.gomeplus.frame.logic.ILogics;
import com.gomeplus.frame.logic.ResultEnum;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.io.*;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/** 
 * @ClassName: MainProjectCreateLogic 
 * @Description: 主项目创建
 * @author chenmin-ds 
 * @date 2017年5月26日 下午2:49:05  
 */
@Service
public class ChildProjectDubboCreateLogic extends AbstractLogic implements ILogics<Map<String , Object>> {

	private Logger logger = LoggerFactory.getLogger("ChildProjectAdminCreateLogic");
	
	public ResultEnum exec(Map<String , Object> map) throws LogicsException {
		try{
			exec1(map);
			
			TblProjectBasicInfo projectBasicInfo = (TblProjectBasicInfo) map.get("projectBasicInfo");
			String pachagesPath = projectBasicInfo.getPackages().replace(".", "//");
			
			String projectPath = projectBasicInfo.getProjectPath().trim();
			if(!projectPath.endsWith("//")){
				projectPath +="//";
				projectBasicInfo.setProjectPath(projectPath);
			}
			
			projectPath += projectBasicInfo.getProjectEng()+"//";
			projectPath += projectBasicInfo.getProjectEng()+"-dubbo";
			//childProjectInfo.setProjectPath(projectPath);
			File file = new File(projectPath+"//src//main//resources//" + projectBasicInfo.getProjectEng());
			if (!file.exists()) {
				file.mkdirs();
			}
			
			file = new File(projectPath+"//src//main//resources//" + projectBasicInfo.getProjectEng() +"//" + projectBasicInfo.getProjectEng() +"-dubbo-consumer.xml");
			if (!file.exists()) {
				file.createNewFile();
			}
			StringBuffer sb = new StringBuffer();
			sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n");
			sb.append("<beans xmlns=\"http://www.springframework.org/schema/beans\" \n");
			sb.append("	xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" \n");
			sb.append("	xmlns:dubbo=\"http://code.alibabatech.com/schema/dubbo\" \n");
			sb.append("	xsi:schemaLocation=\"http://www.springframework.org/schema/beans \n");
			sb.append("			http://www.springframework.org/schema/beans/spring-beans-2.5.xsd \n");
			sb.append("			http://code.alibabatech.com/schema/dubbo \n");
			sb.append("			http://code.alibabatech.com/schema/dubbo/dubbo.xsd\">\n");
			sb.append("  \n");
			sb.append("  <dubbo:consumer check=\"false\" /> \n");
			sb.append("  <dubbo:registry protocol=\"zookeeper\" address=\"${dubbo.run.registryAddress}\" id=\"" + projectBasicInfo.getProjectEng() +"DubboProvider\" /> \n");
			sb.append("  \n");
			sb.append("  <!--dubbo:reference timeout=\"${dubbo.run.timeout}\" group=\"${dubbo.group}\" id=\"realNameQueryFacedeService\" interface=\"cn.com.gome.cardreal.dubbo.RealNameQueryFacedeService\" registry=\"" + projectBasicInfo.getProjectEng() +"DubboProvider\" retries=\"0\" check=\"false\" /-->\n"); 
			sb.append("  \n");
			sb.append("</beans>\n");
			OutputStreamWriter write = new OutputStreamWriter(new FileOutputStream(projectPath+"//src//main//resources//" + projectBasicInfo.getProjectEng() +"//" + projectBasicInfo.getProjectEng() +"-dubbo-consumer.xml"), "UTF-8");
			BufferedWriter writer = new BufferedWriter(write);
			writer.write(sb.toString());
			writer.flush();
			writer.close();
			
			file = new File(projectPath+"//src//main//java//"+pachagesPath+"//"+projectBasicInfo.getProjectEng()+"//dubbo//bean");
			if (!file.exists()) {
				file.mkdirs();
			}
			
			String tfn = projectBasicInfo.getProjectEng().substring(0, 1).toUpperCase() + projectBasicInfo.getProjectEng().substring(1, projectBasicInfo.getProjectEng().length()).toLowerCase();
			
			file = new File(projectPath+"//src//main//java//"+pachagesPath+"//"+projectBasicInfo.getProjectEng()+"//dubbo//bean//"+tfn+"Constants.java");
			if (!file.exists()) {
				file.createNewFile();
			}
			sb = new StringBuffer();
			sb.append("package "+projectBasicInfo.getPackages()+"."+projectBasicInfo.getProjectEng()+".dubbo.bean;\n");
			sb.append("\n");  
			sb.append("public class "+tfn+"Constants {\n");  
			sb.append("	\n");  
			sb.append("	/**返回结果码：0000成功；*/\n");  
			sb.append("	public final static String RESULT_SUCCESS = \"0000\";\n");  
			sb.append("	\n");  
			sb.append("	/**返回结果码：0001，重复入库；*/\n");  
			sb.append("	public final static String RESULT_REPEAT = \"0001\";\n");  
			sb.append("	\n");  
			sb.append("	/**返回结果码：0003，过期。*/\n");  
			sb.append("	public final static String RESULT_EXPIRE = \"0003\"; \n");  
			sb.append("	\n");  
			sb.append("	/**返回结果码：0002，失败。*/ \n");  
			sb.append("	public final static String RESULT_FAIL = \"0002\"; \n");  
			sb.append("\n");  
			sb.append("	/**返回结果码：5555,接口调用权限限制*/\n");  
			sb.append("	public final static String CHANNEL_LIMIT = \"5555\"; \n");  
			sb.append("	\n");  
			sb.append("}\n");  
			write = new OutputStreamWriter(new FileOutputStream(projectPath+"//src//main//java//"+pachagesPath+"//"+projectBasicInfo.getProjectEng()+"//dubbo//bean//"+tfn+"Constants.java"), "UTF-8");
			writer = new BufferedWriter(write);
			writer.write(sb.toString());
			writer.flush();
			writer.close();
			
			file = new File(projectPath+"//src//main//java//"+pachagesPath+"//"+projectBasicInfo.getProjectEng()+"//dubbo//bean//"+tfn+"ParametersVo.java");
			if (!file.exists()) {
				file.createNewFile();
			}
			sb = new StringBuffer();
			sb.append("package "+projectBasicInfo.getPackages()+"."+projectBasicInfo.getProjectEng()+".dubbo.bean; \n");
			sb.append("\n");
			sb.append("import java.io.Serializable;\n");
			sb.append("import java.math.BigDecimal;\n");
			sb.append("import java.util.HashMap;\n");
			sb.append("import java.util.Map;\n");
			sb.append("\n");
			sb.append("import org.apache.commons.lang.StringUtils;\n");
			sb.append("/** \n");
			sb.append(" * @ClassName: "+tfn+"ParametersVo \n");
			sb.append(" * @Description: dubbo服务接口方法请求回调vo \n");
			sb.append(" * @author chenmin-ds \n");
			sb.append(" * @date "+ getCodeGenerateTime()+"  \n");
			sb.append(" */\n");
			sb.append("public class "+tfn+"ParametersVo implements Serializable{\n");
			sb.append("\n");
			sb.append("	private static final long serialVersionUID = -8886267161275214875L;\n");
			sb.append("\n");
			sb.append("	/**业务来源：010，PC端；020，移动端*/\n");
			sb.append("	private String sources;\n");
			sb.append("	\n");
			sb.append("	/**业务版本号，默认:0.1*/\n");
			sb.append("	private String version = \"0.1\";\n");
			sb.append("	\n");
			sb.append("	/**业务类型，与服务层服务类方法同名*/\n");
			sb.append("	private String businessType;\n");
			sb.append("	\n");
			sb.append("	/**日志关联key*/\n");
			sb.append("	private String logAndKey;\n");
			sb.append("	\n");
			sb.append("	/**业务参数集合*/\n");
			sb.append("	private Map<String , Object> map = null;\n");
			sb.append("	\n");
			sb.append("	/**错误码：0000,成功；0001,重复请求；0002,失败；其它错误码自定*/\n");
			sb.append("	private String resCode;\n");
			sb.append("	\n");
			sb.append("	/**错误信息，默认为“成功”*/\n");
			sb.append("	private String resDesc;\n");
			sb.append("	\n");
			sb.append("	public "+tfn+"ParametersVo(){\n");
			sb.append("		map = new HashMap<String , Object>();\n");
			sb.append("	}\n");
			sb.append("	\n");
			sb.append("	public "+tfn+"ParametersVo(String sources){\n");
			sb.append("		this.sources = sources;\n");
			sb.append("		map = new HashMap<String , Object>();\n");
			sb.append("	}\n");
			sb.append("	\n");
			sb.append("	public "+tfn+"ParametersVo(String sources , String businessType){\n");
			sb.append("		this.sources = sources;\n");
			sb.append("		this.businessType = businessType;\n");
			sb.append("		map = new HashMap<String , Object>();\n");
			sb.append("	}\n");
			sb.append("\n");
			sb.append("	/**业务来源：010，PC端；020，移动端*/\n");
			sb.append("	public String getSources() {\n");
			sb.append("		return sources;\n");
			sb.append("	}\n");
			sb.append("\n");
			sb.append("	/**业务来源：01，PC端；02，移动端*/\n");
			sb.append("	public void setSources(String sources) {\n");
			sb.append("		this.sources = sources;\n");
			sb.append("	}\n");
			sb.append("\n");
			sb.append("	/**日志关联key*/\n");
			sb.append("	public String getLogAndKey() {\n");
			sb.append("		return logAndKey;\n");
			sb.append("	}\n");
			sb.append("\n");
			sb.append("	/**日志关联key*/\n");
			sb.append("	public void setLogAndKey(String logAndKey) {\n");
			sb.append("		this.logAndKey = logAndKey;\n");
			sb.append("	}\n");
			sb.append("\n");
			sb.append("	/**业务版本号，默认:0.1*/\n");
			sb.append("	public String getVersion() {\n");
			sb.append("		return version;\n");
			sb.append("	}\n");
			sb.append("\n");
			sb.append("	/**业务版本号，默认:0.1*/\n");
			sb.append("	public void setVersion(String version) {\n");
			sb.append("		this.version = version;\n");
			sb.append("	}\n");
			sb.append("\n");
			sb.append("	/**业务类型，与服务层服务类方法同名*/\n");
			sb.append("	public String getBusinessType() {\n");
			sb.append("		return businessType;\n");
			sb.append("	}\n");
			sb.append("\n");
			sb.append("	/**业务类型，与服务层服务类方法同名*/\n");
			sb.append("	public void setBusinessType(String businessType) {\n");
			sb.append("		this.businessType = businessType;\n");
			sb.append("	}\n");
			sb.append("	\n");
			sb.append("	/**业务参数*/\n");
			sb.append("	public void setInfo(String key , Object value){\n");
			sb.append("		map.put(key, value);\n");
			sb.append("	}\n");
			sb.append("	\n");
			sb.append("	/**业务参数*/\n");
			sb.append("	public Object getInfo(String key){\n");
			sb.append("		return map.get(key);\n");
			sb.append("	}\n");
			sb.append("	\n");
			sb.append("	/**业务参数*/\n");
			sb.append("	public String getString(String key){\n");
			sb.append("		Object obj = map.get(key);\n");
			sb.append("		String returnValue = \"\";\n");
			sb.append("		if(obj != null){\n");
			sb.append("			if(obj.getClass().getSimpleName().equals(\"BigDecimal\")){\n");
			sb.append("				returnValue =((BigDecimal) obj).toPlainString();\n");
			sb.append("			}else{\n");
			sb.append("				returnValue = String.valueOf(obj);\n");
			sb.append("			}\n");
			sb.append("		}\n");
			sb.append("		return returnValue;\n");
			sb.append("	}\n");
			sb.append("	\n");
			sb.append("	/**业务参数*/\n");
			sb.append("	public BigDecimal getBigDecimal(String key){\n");
			sb.append("		Object obj = map.get(key);\n");
			sb.append("		if(obj != null){\n");
			sb.append("			if(obj.getClass().getSimpleName().equals(\"BigDecimal\")){\n");
			sb.append("				return ((BigDecimal) obj);\n");
			sb.append("			}else{\n");
			sb.append("				return new BigDecimal(String.valueOf(obj));\n");
			sb.append("			}\n");
			sb.append("		}\n");
			sb.append("		return null;\n");
			sb.append("	}\n");
			sb.append("	\n");
			sb.append("	/**业务参数*/\n");
			sb.append("	public Integer getInt(String key){\n");
			sb.append("		Object obj = map.get(key);\n");
			sb.append("		if(obj != null){\n");
			sb.append("			if(obj.getClass().getSimpleName().equals(\"Integer\")){\n");
			sb.append("				return (Integer) obj;\n");
			sb.append("			}else{\n");
			sb.append("				return Integer.valueOf(String.valueOf(obj));\n");
			sb.append("			}\n");
			sb.append("		}\n");
			sb.append("		return null;\n");
			sb.append("	}\n");
			sb.append("	\n");
			sb.append("	@Override\n");
			sb.append("	public String toString() {\n");
			sb.append("		StringBuffer resultStr = new StringBuffer();\n");
			sb.append("		resultStr.append(\" businessType: \" + this.getBusinessType());\n");
			sb.append("		resultStr.append(\" sources: \" + this.getSources());\n");
			sb.append("		resultStr.append(\" version: \" + this.getVersion());\n");
			sb.append("		resultStr.append(\" logAndKey: \" + this.getLogAndKey());\n");
			sb.append("		if(!StringUtils.isEmpty(this.getResCode())){\n");
			sb.append("			resultStr.append(\" resCode: \" + this.getResCode());\n");
			sb.append("			resultStr.append(\" resDesc: \" + this.getResDesc());\n");
			sb.append("		}\n");
			sb.append("		resultStr.append(\" map: \" + this.map.toString());\n");
			sb.append("		return resultStr.toString();\n");
			sb.append("		\n");
			sb.append("	}\n");
			sb.append("	\n");
			sb.append("	public void remove(String key){\n");
			sb.append("		map.remove(key);\n");
			sb.append("	}\n");
			sb.append("\n");
			sb.append("	/**错误码：0000,成功；0001,重复请求；0002,失败；其它错误码自定*/\n");
			sb.append("	public String getResCode() {\n");
			sb.append("		return resCode;\n");
			sb.append("	}\n");
			sb.append("\n");
			sb.append("	/**错误码：0000,成功；0001,重复请求；0002,失败；其它错误码自定*/\n");
			sb.append("	public void setResCode(String resCode) {\n");
			sb.append("		this.resCode = resCode;\n");
			sb.append("	}\n");
			sb.append("\n");
			sb.append("	/**错误信息，默认为“成功”*/\n");
			sb.append("	public String getResDesc() {\n");
			sb.append("		return resDesc;\n");
			sb.append("	}\n");
			sb.append("\n");
			sb.append("	/**错误信息，默认为“成功”*/\n");
			sb.append("	public void setResDesc(String resDesc) {\n");
			sb.append("		this.resDesc = resDesc;\n");
			sb.append("	}\n");
			sb.append("\n");
			sb.append("	public Map<String, Object> getMap() {\n");
			sb.append("		return map;\n");
			sb.append("	}\n");
			sb.append("\n");
			sb.append("	public void setMap(Map<String, Object> map) {\n");
			sb.append("		this.map = map;\n");
			sb.append("	}\n");
			sb.append("}\n");
			write = new OutputStreamWriter(new FileOutputStream(projectPath+"//src//main//java//"+pachagesPath+"//"+projectBasicInfo.getProjectEng()+"//dubbo//bean//"+tfn+"ParametersVo.java"), "UTF-8");
			writer = new BufferedWriter(write);
			writer.write(sb.toString());
			writer.flush();
			writer.close();
			
			
			return ResultEnum.OK;
		}catch(Exception e){
			logger.error("创建子项目异常：",e);
		}
		return ResultEnum.PART_CASE_01;
	}

	public ResultEnum exec1(Map<String , Object> map) throws LogicsException {
		try{
			TblProjectBasicInfo projectBasicInfo = (TblProjectBasicInfo) map.get("projectBasicInfo");
			String pachagesPath = projectBasicInfo.getPackages().replace(".", "//");
			
			String projectPath = projectBasicInfo.getProjectPath().trim();
			if(!projectPath.endsWith("//")){
				projectPath +="//";
				projectBasicInfo.setProjectPath(projectPath);
			}
			
			projectPath += projectBasicInfo.getProjectEng()+"//";
			projectPath += projectBasicInfo.getProjectEng()+"-dubbo";
			//childProjectInfo.setProjectPath(projectPath);
			File file = new File(projectPath);
			if(!file.exists()){
				file.mkdir();
			}
			
			file = new File(projectPath+"//src//main//resources");
			if (!file.exists()) {
				file.mkdirs();
			}
			file = new File(projectPath+"//src//main//java");
			if (!file.exists()) {
				file.mkdirs();
			}
			file = new File(projectPath+"//src//test//java//"+pachagesPath+"//"+projectBasicInfo.getProjectEng()+"//dubbo");
			if (!file.exists()) {
				file.mkdirs();
			}
			
			projectPath += "//pom.xml";
			file = new File(projectPath);
			if(!file.exists()){
				file.createNewFile();
			}
			
			StringBuffer sb = new StringBuffer();
			sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
			sb.append("<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n");
			sb.append("	xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n");
			sb.append("	<modelVersion>4.0.0</modelVersion>\n");
			sb.append("	<parent>\n");
			sb.append("		<groupId>"+projectBasicInfo.getPackages()+"</groupId>\n");
			sb.append("		<artifactId>" + projectBasicInfo.getProjectEng() + "</artifactId>\n");
			sb.append("		<version>0.0.1-SNAPSHOT</version>\n");
			sb.append("	</parent>\n");
			sb.append("	<groupId>"+projectBasicInfo.getPackages()+"</groupId>\n"); 
			sb.append("	<artifactId>" + projectBasicInfo.getProjectEng() + "-dubbo</artifactId>\n");
			sb.append("	<version>0.0.1-SNAPSHOT</version>\n"); 
			sb.append("	<packaging>jar</packaging>\n");
			sb.append("	<name>" + projectBasicInfo.getProjectEng() + "-dubbo</name>\n");
			sb.append("	<url>http://maven.apache.org</url>\n");

			sb.append("	<dependencies>\n");
			sb.append("	<dependency>\n");
			sb.append("		<groupId>commons-lang</groupId>\n");
			sb.append("		<artifactId>commons-lang</artifactId>\n");
			sb.append("		<version>2.5</version>\n");
			sb.append("	</dependency>\n");
			sb.append("	</dependencies>\n");


			sb.append("	<build>\n");
			sb.append("		<resources>\n");
			sb.append("			<resource>\n");
			sb.append("				<directory>src/main/resources</directory>\n");
			sb.append("				<filtering>true</filtering>\n");
			sb.append("			</resource>\n");
			sb.append("		</resources>\n");
			sb.append("	</build>\n");
			
			sb.append("<profiles>\n");
			sb.append("	<profile>\n");
			sb.append("		<id>dev</id>\n");
			sb.append("		<properties>\n");
			sb.append("			<env>dev</env>\n");
			sb.append("		</properties>\n");
			sb.append("	</profile>\n");
			sb.append("	<profile>\n");
			sb.append("		<id>uat</id>\n");
			sb.append("		<activation>\n");
			sb.append("			<activeByDefault>true</activeByDefault>\n");
			sb.append("		</activation>\n");
			sb.append("		<properties>\n");
			sb.append("			<env>uat</env>\n");
			sb.append("		</properties>\n");
			sb.append("	</profile>\n");
			sb.append("	<profile>\n");
			sb.append("		<id>pre</id>\n");
			sb.append("		<properties>\n");
			sb.append("			<env>pre</env>\n");
			sb.append("		</properties>\n");
			sb.append("	</profile>\n");
			sb.append("	<profile>\n");
			sb.append("		<id>live</id>\n");
			sb.append("		<properties>\n");
			sb.append("			<env>live</env>\n");
			sb.append("		</properties>\n");
			sb.append("	</profile>\n");
			sb.append("	<profile>\n");
			sb.append("		<id>drill</id>\n");
			sb.append("		<properties>\n");
			sb.append("			<env>live</env>\n");
			sb.append("		</properties>\n");
			sb.append("	</profile>\n");
			sb.append("</profiles>\n");

			sb.append("</project>");
			OutputStreamWriter write = new OutputStreamWriter(new FileOutputStream(projectPath), "UTF-8");
			BufferedWriter writer = new BufferedWriter(write);
			writer.write(sb.toString());
			writer.flush();
			writer.close();
			editPomXml(projectBasicInfo.getProjectPath(),projectBasicInfo.getProjectEng(),"dubbo");
			return ResultEnum.OK;
		}catch(Exception e){
			logger.error("创建子项目异常：",e);
		}
		return ResultEnum.PART_CASE_01;
	}

	@SuppressWarnings("rawtypes")
	public void editPomXml(String projectPath, String projectEng, String CHILD_PROJECT_ENG) throws IOException {
		projectPath += projectEng + "//pom.xml";
		File file = new File(projectPath);
		SAXReader reader = new SAXReader();
		try {
			Document doc = reader.read(file);
			Element elementR = doc.getRootElement();
			Element element = elementR.element("modules");
			boolean t = true;
			if(element != null && element.elements().size() > 0){
				List list1 = element.elements();
				Iterator iterator = list1.iterator();
				while(iterator.hasNext()){
					Element elem = (Element) iterator.next();
					if((projectEng + "-" + CHILD_PROJECT_ENG).equals(elem.getText())){
						t = false;
					}
				}
			}
			if(t){
				Element date = element.addElement("module");
				date.addText(projectEng + "-" + CHILD_PROJECT_ENG);
				FileWriter newFile = new FileWriter(new File(projectPath));
	            XMLWriter newWriter = new XMLWriter(newFile);
	            newWriter.write(doc);
	            newWriter.close();
			}
		} catch (DocumentException e) {
			e.printStackTrace();
		}
	}
}
